import { ChangeDetectionStrategy, Component, Input, ViewChild, ChangeDetectorRef } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ButtonComponent } from './button.component';

@Component({
  template: `
    <button
      lv-button
      #buttonComponent
      [disabled]="disabled"
      [lvType]="lvType"
      [lvSize]="lvSize"
      [lvLoading]="lvLoading"
      [lvDanger]="lvDanger"
      [lvLoadingText]="lvLoadingText"
      (click)="click()"
    >
      Button
    </button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestButtonBasicComponent {
  @ViewChild('buttonComponent', { static: true }) buttonComponent: ButtonComponent;
  @Input() lvType: ButtonComponent['lvType'];
  @Input() lvSize: ButtonComponent['lvSize'];
  @Input() lvLoading: boolean;
  @Input() lvLoadingText: string;
  @Input() lvDanger: boolean;
  @Input() disabled: boolean;

  click() {}
}

describe('ButtonComponent', () => {
  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [ButtonComponent, TestButtonBasicComponent],
    }).compileComponents;
  }));

  describe('render', () => {
    let component: TestButtonBasicComponent;
    let fixture: ComponentFixture<TestButtonBasicComponent>;
    let cdr: ChangeDetectorRef;

    beforeEach(() => {
      fixture = TestBed.createComponent(TestButtonBasicComponent);
      component = fixture.componentInstance;
      cdr = fixture.debugElement.injector.get(ChangeDetectorRef);
      component.lvType = 'primary';
      component.lvSize = 'default';
      fixture.detectChanges();
    });

    // 按钮尺寸渲染
    it('size should render correctly', () => {
      component.lvSize = 'auto';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvSize = 'small';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvSize = 'large';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvSize = 'default';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    // primary按钮状态渲染
    it('primary button should render correctly', () => {
      component.disabled = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = false;
      component.lvLoading = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    // default按钮状态渲染
    it('default button should render correctly', () => {
      component.lvType = 'default';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = false;
      component.lvLoading = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    // link按钮状态渲染
    it('link button should render correctly', () => {
      component.lvType = 'link';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = false;
      component.lvLoading = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    // danger按钮状态渲染
    it('danger button should render correctly', () => {
      component.lvDanger = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.disabled = false;
      component.lvLoading = true;
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });
  });

  describe('basic', () => {
    let component: TestButtonBasicComponent;
    let fixture: ComponentFixture<TestButtonBasicComponent>;

    beforeEach(() => {
      fixture = TestBed.createComponent(TestButtonBasicComponent);
      component = fixture.componentInstance;
      component.lvType = 'primary';
      component.lvSize = 'default';
      jest.spyOn(component, 'click');
    });

    // TODO: 按钮loading状态下，无法点击

    it('should custom loading text', () => {
      component.lvLoading = true;
      component.lvLoadingText = 'loading';
      fixture.detectChanges();
      const span = fixture.nativeElement.querySelector('span:nth-child(2)');
      expect(span.textContent).toContain('loading');
    });
  });
});
